package com.gengzp.system.service.impl;

import com.gengzp.common.enums.IterationStatusEnum;
import com.gengzp.common.enums.YesNoEnum;
import com.gengzp.common.exception.BusinessException;
import com.gengzp.common.model.pagination.resp.PaginationResponse;
import com.gengzp.common.model.user.entity.SysUser;
import com.gengzp.common.model.versionIteration.dto.VersionIterationDeveloperDto;
import com.gengzp.common.model.versionIteration.entity.VersionIteration;
import com.gengzp.common.model.versionIteration.req.ChangeVersionIterationStatusReq;
import com.gengzp.common.model.versionIteration.req.CreateVersionIterationReq;
import com.gengzp.common.model.versionIteration.req.EditVersionIterationReq;
import com.gengzp.common.model.versionIteration.req.PageVersionIterationReq;
import com.gengzp.common.model.versionIteration.resp.PageVersionIterationResp;
import com.gengzp.common.model.versionIteration.resp.SearchVersionIterationResp;
import com.gengzp.common.utils.ThreadUtils;
import com.gengzp.system.facade.SysUserFacade;
import com.gengzp.system.mapper.VersionIterationMapper;
import com.gengzp.system.service.VersionIterationService;
import com.gengzp.system.utils.OperatorInfoUtils;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;
import java.util.stream.Collectors;

/**
 * @ClassName VersionIterationServiceImpl
 * @Description 版本迭代模块服务层实现类
 * @Author gengzp
 * @Date 2025/10/11 16:28
 */
@Service
public class VersionIterationServiceImpl implements VersionIterationService {

    private static final Logger logger = LoggerFactory.getLogger(VersionIterationServiceImpl.class);

    @Autowired
    private VersionIterationMapper versionIterationMapper;

    @Autowired
    private SysUserFacade sysUserFacade;

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void createVersionIteration(CreateVersionIterationReq req) {
        // 重复值校验
        List<String> errorMessages = ThreadUtils.batchExecute(() -> {
            if (Objects.nonNull(versionIterationMapper.selectVersionIterationByVersion(req.getVersion()))) {
                throw BusinessException.get(String.format("版本号【%s】已存在，无法重复创建", req.getVersion()));
            }
        }, () -> {
            if (Objects.nonNull(versionIterationMapper.selectVersionIterationByTitle(req.getTitle()))) {
                throw BusinessException.get(String.format("迭代标题【%s】已存在，无法重复创建", req.getTitle()));
            }
        }, () -> {
            if (Objects.nonNull(versionIterationMapper.selectVersionIterationByBranchName(req.getBranchName()))) {
                throw BusinessException.get(String.format("分支名【%s】已存在，无法重复创建", req.getBranchName()));
            }
        });
        if (CollectionUtils.isNotEmpty(errorMessages)) {
            throw BusinessException.get(String.join("；", errorMessages));
        }

        VersionIteration versionIteration = new VersionIteration();
        versionIteration.setTitle(req.getTitle());
        versionIteration.setVersion(req.getVersion());
        versionIteration.setDescription(req.getDescription());
        versionIteration.setStatus(IterationStatusEnum.UN_STARTED.getCode());
        versionIteration.setBranchName(req.getBranchName());
        versionIteration.setFrontEndDevelopers(req.getFrontEndDevelopers());
        versionIteration.setBackEndDevelopers(req.getBackEndDevelopers());
        versionIteration.setIsDeleted(YesNoEnum.NO.getCode());
        versionIterationMapper.insertVersionIteration(versionIteration);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void editVersionIterationById(EditVersionIterationReq req) {
        VersionIteration versionIteration = versionIterationMapper.selectVersionIterationById(Long.valueOf(req.getId()));
        if (Objects.isNull(versionIteration)) {
            throw BusinessException.get("当前迭代id不存在，无法编辑");
        }

        // 重复值校验
        if ((Objects.equals(req.getTitle(), versionIteration.getTitle()) ||
                Objects.equals(req.getBranchName(), versionIteration.getBranchName()))) {
            if (!Objects.equals(versionIteration.getStatus(), IterationStatusEnum.UN_STARTED.getCode())) {
                throw BusinessException.get("当前迭代已开始，无法修改迭代标题和分支名");
            }
            List<String> errorMessages = ThreadUtils.batchExecute(() -> {
                VersionIteration iterationByTitle = versionIterationMapper.selectVersionIterationByTitle(req.getTitle());
                if (Objects.nonNull(iterationByTitle) && !Objects.equals(iterationByTitle.getId(), versionIteration.getId())) {
                    throw BusinessException.get(String.format("迭代标题【%s】已存在", req.getTitle()));
                }
            }, () -> {
                VersionIteration iterationByBranchName = versionIterationMapper.selectVersionIterationByBranchName(req.getBranchName());
                if (Objects.nonNull(iterationByBranchName) && !Objects.equals(iterationByBranchName.getId(), versionIteration.getId())) {
                    throw BusinessException.get(String.format("分支名【%s】已存在", req.getBranchName()));
                }
            });
            if (CollectionUtils.isNotEmpty(errorMessages)) {
                throw BusinessException.get(String.join("；", errorMessages));
            }
        }

        versionIteration.setTitle(req.getTitle());
        versionIteration.setDescription(req.getDescription());
        versionIteration.setBranchName(req.getBranchName());
        versionIteration.setFrontEndDevelopers(req.getFrontEndDevelopers());
        versionIteration.setBackEndDevelopers(req.getBackEndDevelopers());
        versionIterationMapper.updateVersionIterationById(versionIteration);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void changeVersionIterationStatusById(ChangeVersionIterationStatusReq req) {
        VersionIteration versionIteration = versionIterationMapper.selectVersionIterationById(Long.valueOf(req.getId()));
        if (Objects.isNull(versionIteration)) {
            throw BusinessException.get("当前迭代id不存在，无法编辑");
        }
        if (Objects.equals(versionIteration.getStatus(), IterationStatusEnum.COMPLETED.getCode())) {
            throw BusinessException.get("当前迭代已经是已完成状态，无法再进行修改");
        }
        if (req.getStatus() <= versionIteration.getStatus()) {
            throw BusinessException.get("当前迭代状态已处于【" +
                    IterationStatusEnum.getValueByCode(versionIteration.getStatus()) + "】状态，无法进行回退操作");
        }

        versionIteration.setStatus(req.getStatus());
        if (Objects.equals(req.getStatus(), IterationStatusEnum.COMPLETED.getCode())) {
            versionIteration.setReleaseTime(new Date());
        }
        versionIterationMapper.updateVersionIterationById(versionIteration);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public void removeVersionIterationById(Long id) {
        versionIterationMapper.deleteVersionIterationById(id);
    }

    @Override
    public SearchVersionIterationResp searchVersionIterationById(Long id) {
        VersionIteration versionIteration = versionIterationMapper.selectVersionIterationById(id);
        if (Objects.isNull(versionIteration)) {
            throw BusinessException.get("当前版本迭代信息不存在");
        }

        SearchVersionIterationResp resp = new SearchVersionIterationResp();
        resp.setId(String.valueOf(versionIteration.getId()));
        resp.setTitle(versionIteration.getTitle());
        resp.setVersion(versionIteration.getVersion());
        resp.setDescription(versionIteration.getDescription());
        resp.setStatus(versionIteration.getStatus());
        resp.setStatusValue(IterationStatusEnum.getValueByCode(versionIteration.getStatus()));
        resp.setBranchName(versionIteration.getBranchName());
        resp.setReleaseTime(versionIteration.getReleaseTime());
        resp.setFrontEndDeveloperDtos(Lists.newArrayList());
        resp.setBackEndDeveloperDtos(Lists.newArrayList());
        resp.setCreatedTime(versionIteration.getCreatedTime());
        resp.setCreatedBy(String.valueOf(versionIteration.getCreatedBy()));
        resp.setLastModifiedTime(versionIteration.getLastModifiedTime());
        resp.setLastModifiedBy(String.valueOf(versionIteration.getLastModifiedBy()));
        // 填充用户信息
        fillInGenericRespUserInfo(versionIteration, resp);

        return resp;
    }

    @Override
    public PaginationResponse<PageVersionIterationResp> pageQueryVersionIterationResp(PageVersionIterationReq req) {
        List<VersionIteration> versionIterations = versionIterationMapper.pageQueryVersionIteration(req);
        if (CollectionUtils.isEmpty(versionIterations)) {
            return PaginationResponse.get(Lists.newArrayList(), req);
        }

        List<PageVersionIterationResp> result = Lists.newArrayList();
        for (VersionIteration versionIteration : versionIterations) {
            PageVersionIterationResp resp = new PageVersionIterationResp();
            resp.setId(String.valueOf(versionIteration.getId()));
            resp.setTitle(versionIteration.getTitle());
            resp.setVersion(versionIteration.getVersion());
            resp.setStatus(versionIteration.getStatus());
            resp.setStatusValue(IterationStatusEnum.getValueByCode(versionIteration.getStatus()));
            resp.setBranchName(versionIteration.getBranchName());
            resp.setReleaseTime(versionIteration.getReleaseTime());
            resp.setCreatedTime(versionIteration.getCreatedTime());
            resp.setCreatedBy(String.valueOf(versionIteration.getCreatedBy()));
            resp.setLastModifiedTime(versionIteration.getLastModifiedTime());
            resp.setLastModifiedBy(String.valueOf(versionIteration.getLastModifiedBy()));
            result.add(resp);
        }
        // 填充操作人信息
        OperatorInfoUtils.fillInGenericRespOperatorInformation(result);

        return PaginationResponse.get(result, req);
    }

    /**
     * 填充版本迭代详情的用户信息
     *
     * @param versionIteration 版本迭代信息
     */
    private void fillInGenericRespUserInfo(VersionIteration versionIteration, SearchVersionIterationResp resp) {
        // 前端开发id集合
        List<Long> frontEndDeveloperUserIds = Optional.ofNullable(versionIteration.getFrontEndDevelopers())
                .map(v -> Arrays.stream(v.split(",")).map(Long::valueOf).collect(Collectors.toList()))
                .orElse(Collections.emptyList());
        // 后端开发id集合
        List<Long> backEndDeveloperUserIds = Optional.ofNullable(versionIteration.getBackEndDevelopers())
                .map(v -> Arrays.stream(v.split(",")).map(Long::valueOf).collect(Collectors.toList()))
                .orElse(Collections.emptyList());
        // 所有涉及到的用户id集合
        List<Long> involvedUserIds = Lists.newArrayList();
        involvedUserIds.addAll(frontEndDeveloperUserIds);
        involvedUserIds.addAll(backEndDeveloperUserIds);
        involvedUserIds.add(versionIteration.getCreatedBy());
        involvedUserIds.add(versionIteration.getLastModifiedBy());

        // 所有涉及到的用户id对应昵称映射
        Map<Long, String> userId2NicknameMap = Maps.newHashMap();
        List<SysUser> sysUsers = sysUserFacade.searchSysUsersByIds(involvedUserIds);
        if (CollectionUtils.isNotEmpty(sysUsers)) {
            userId2NicknameMap = sysUsers.stream().collect(Collectors.toMap(SysUser::getId, SysUser::getUserNickname));
        }

        // 填充前端开发用户信息
        if (CollectionUtils.isNotEmpty(frontEndDeveloperUserIds)) {
            for (Long userId : frontEndDeveloperUserIds) {
                VersionIterationDeveloperDto dto = new VersionIterationDeveloperDto();
                dto.setUserId(userId.toString());
                dto.setUserNickname(userId2NicknameMap.getOrDefault(userId, "该用户已不存在"));
                resp.getFrontEndDeveloperDtos().add(dto);
            }
        }

        // 填充后端开发用户信息
        if (CollectionUtils.isNotEmpty(backEndDeveloperUserIds)) {
            for (Long userId : backEndDeveloperUserIds) {
                VersionIterationDeveloperDto dto = new VersionIterationDeveloperDto();
                dto.setUserId(userId.toString());
                dto.setUserNickname(userId2NicknameMap.getOrDefault(userId, "该用户已不存在"));
                resp.getBackEndDeveloperDtos().add(dto);
            }
        }

        // 填充操作人用户信息
        resp.setCreatedByUserNickname(userId2NicknameMap.getOrDefault(versionIteration.getCreatedBy(), "该用户已不存在"));
        resp.setLastModifiedByUserNickname(userId2NicknameMap.getOrDefault(versionIteration.getLastModifiedBy(), "该用户已不存在"));
    }

}
